﻿using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.ComponentModel;

namespace Cartoons
{
    public partial class DeepZoomBook
    {
        #region DP declarations

        public static readonly DependencyProperty BookSourceProperty =
            DependencyProperty.Register("BookSource", typeof(Uri), typeof(DeepZoomBook), new PropertyMetadata(null, OnBookSourceChanged));

        public static readonly DependencyProperty AllowMouseZoomProperty =
            DependencyProperty.Register("AllowMouseZoom", typeof(bool), typeof(DeepZoomBook), new PropertyMetadata(true));

        public static readonly DependencyProperty ZoomProperty =
            DependencyProperty.Register("Zoom", typeof(double), typeof(DeepZoomBook), new PropertyMetadata(1.0, OnZoomChanged));

        public static readonly DependencyProperty PagingFactorProperty =
            DependencyProperty.Register("PagingFactor", typeof(double), typeof(DeepZoomBook), new PropertyMetadata(1.0));

        public static readonly DependencyProperty BroadsideProperty =
            DependencyProperty.Register("Broadside", typeof(double), typeof(DeepZoomBook), new PropertyMetadata(0.0, OnBroadsideChanged));

        public static readonly DependencyProperty SelectedBroadsideProperty =
            DependencyProperty.Register("SelectedBroadside", typeof(int), typeof(DeepZoomBook), new PropertyMetadata(0, OnSelectedBroadsideChanged));

        public static readonly DependencyProperty DefaultTransitionsTimeProperty =
            DependencyProperty.Register("DefaultTransitionsTime", typeof(TimeSpan), typeof(DeepZoomBook), new PropertyMetadata(new TimeSpan(0, 0, 1)));



        #endregion

        #region Behavior

        private static void OnBookSourceChanged(object target, DependencyPropertyChangedEventArgs e)
        {
            var book = target as DeepZoomBook;

            if (book == null)
                return;

            book.ChangeBookSource(e.NewValue as Uri);
        }

        private static void OnSelectedBroadsideChanged(object target, DependencyPropertyChangedEventArgs e)
        {
            var book = target as DeepZoomBook;

            if (book == null)
                return;

            if (!(e.NewValue is int))
                return;

            var token = DPCancelationToken.GetCancelationToken(book, e.Property);
            if (token.IsCancelling)
            {
                token.Finish();
                return;
            }

            if (book.ChangeSelectedBroadside((int)e.OldValue, (int)e.NewValue))
                return;

            token.Cancel(e.OldValue);
        }

        private static void OnBroadsideChanged(object target, DependencyPropertyChangedEventArgs e)
        {
            var book = target as DeepZoomBook;

            if (!(e.NewValue is double && e.OldValue is double))
                return;

            var newBroadside = (double)e.NewValue;

            var oldBroadside = (double)e.OldValue;

            var token = DPCancelationToken.GetCancelationToken(book, e.Property);
            if (token.IsCancelling)
            {
                token.Finish();
                return;
            }

            if (book.ChangeBroadside(oldBroadside, newBroadside))
                return;

            token.Cancel(e.OldValue);
        }

        private static void OnZoomChanged(object target, DependencyPropertyChangedEventArgs e)
        {
            var book = target as DeepZoomBook;

            if (book == null)
                return;

            if (!(e.NewValue is double && e.OldValue is double))
                return;

            var token = DPCancelationToken.GetCancelationToken(book, e.Property);
            if (token.IsCancelling)
            {
                token.Finish();
                return;
            }

            var oldZoom = (double)e.OldValue;
            var newZoom = (double)e.NewValue;

            if (book.ChangeZoom(oldZoom, newZoom))
                return;

            token.Cancel(e.OldValue);
        }

        #endregion

        #region Scalar properties

        public TimeSpan DefaultTransitionsTime
        {
            get { return (TimeSpan)GetValue(DefaultTransitionsTimeProperty); }
            set { SetValue(DefaultTransitionsTimeProperty, value); }
        }

        public double Broadside
        {
            get { return (double)GetValue(BroadsideProperty); }
            set { SetValue(BroadsideProperty, value); }
        }

        private int SelectedBroadside
        {
            get { return (int)GetValue(SelectedBroadsideProperty); }
            set { SetValue(SelectedBroadsideProperty, value); }
        }

        public double Zoom
        {
            get { return (double)GetValue(ZoomProperty); }
            set { SetValue(ZoomProperty, value); }
        }

        private double PagingFactor
        {
            get { return (double)GetValue(PagingFactorProperty); }
            set { SetValue(PagingFactorProperty, value); }
        }

        public Uri BookSource
        {
            get { return (Uri)GetValue(BookSourceProperty); }
            set { SetValue(BookSourceProperty, value); }
        }

        public bool AllowMouseZoom
        {
            get { return (bool)GetValue(AllowMouseZoomProperty); }
            set { SetValue(AllowMouseZoomProperty, value); }
        }

        #endregion
    }
}
